package com.tengits.mqttmonitor.rnlibs.update;

import android.Manifest;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.provider.Settings;
import android.text.TextUtils;
import android.widget.Toast;
import android.util.Log;

import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AlertDialog;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;

import java.io.File;

import com.facebook.react.bridge.ActivityEventListener;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.LifecycleEventListener;
import com.facebook.react.bridge.BaseActivityEventListener;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.modules.core.PermissionAwareActivity;
import com.facebook.react.modules.core.PermissionListener;

public class UpgradeLibraryModule extends ReactContextBaseJavaModule implements LifecycleEventListener, PermissionListener {

    private static final String TAG = UpgradeLibraryModule.class.getSimpleName();
    private static final int MY_PERMISSIONS_REQUEST_WRITE_STORAGE = 1002;

    private final ReactApplicationContext reactContext;
    private BroadcastReceiver mBroadcastReceiver;
    private LocalBroadcastManager mBroadcastManager;
    private String installPath;

    private Promise promise;

    private String versionUrl;
    private boolean progress;

    private final ActivityEventListener mActivityEventListener = new BaseActivityEventListener() {

        @Override
        public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) {
            if (resultCode == Activity.RESULT_OK && requestCode == InstallUtils.UNKNOWN_CODE && !TextUtils.isEmpty(installPath)) {
                File testFile = new File(installPath);
                if(testFile.exists()) {
                    InstallUtils.install(getCurrentActivity(), installPath);
                }
            }
        }
    };

    public UpgradeLibraryModule(ReactApplicationContext reactContext) {
        super(reactContext);
        this.reactContext = reactContext;
        this.reactContext.addLifecycleEventListener(this);
        this.reactContext.addActivityEventListener(mActivityEventListener);
        mBroadcastReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, final Intent intent) { // 所有任务完成后，都会发广播过来
                if ("download_apk_broadcast".equals(intent.getAction())) { // 需要同步数据
                    installPath = intent.getStringExtra("path");
                    InstallUtils.install(getCurrentActivity(), installPath);
                }
            }
        };

        IntentFilter filter = new IntentFilter();
        filter.addAction("download_apk_broadcast");
        try{
            mBroadcastManager = LocalBroadcastManager.getInstance(reactContext);
            mBroadcastManager.registerReceiver(mBroadcastReceiver, filter);
        }catch(Exception e) {
            Log.e("UpgradeLibraryModule", e.getMessage());
        }
    }

    @Override
    public String getName() {
        return "UpgradeLibrary";
    }

    @ReactMethod
    public void doNewVersionUpdate(final String versionUrl, final boolean progress,
                                   final Promise promise) {
        final Activity activity = getCurrentActivity();
        if(versionUrl.startsWith("http")) {
            if(InstallUtils.isRoot()) {
                this.doRootDownloadInstall(activity, versionUrl, progress, promise);
            } else {
                this.doUnRootDownloadInstall((PermissionAwareActivity) activity, versionUrl, progress, promise);
            }
        } else {
            InstallUtils.install(activity, versionUrl);
        }
    }

    @ReactMethod
    public void getDownloadPath(final  Promise promise) {
        promise.resolve(PathUtils.appDownLoadPath());
    }

    private void doRootDownloadInstall(final Activity activity, final String versionUrl, final boolean progress, final Promise promise) {
        if (NetUtils.isOnline(activity)) {
            new VersionUpdateAsyncTask(activity, progress)
                    .execute(new String[]{versionUrl});
            promise.resolve("positive");
        } else {
            Toast.makeText(activity, "网络出错,请稍后再试", Toast.LENGTH_LONG).show();
            promise.resolve("negative");
        }
    }

    private void doUnRootDownloadInstall(final PermissionAwareActivity activity, final String versionUrl, final boolean progress, final Promise promise) {
        this.promise = promise;
        this.versionUrl = versionUrl;
        this.progress = progress;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && activity.checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
                != PackageManager.PERMISSION_GRANTED) {
            activity.requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, MY_PERMISSIONS_REQUEST_WRITE_STORAGE, this);
        } else {
            doUnRootDownloadInstallImpl((Activity) activity, versionUrl, progress, promise);
        }
    }

    private void doUnRootDownloadInstallImpl(final  Activity activity, final String versionUrl, final boolean progress, final Promise promise) {
        if(checkInstallPermission(activity)) {
            if (NetUtils.isOnline(activity)) {
                new VersionUpdateAsyncTask(activity, progress)
                        .execute(new String[]{versionUrl});
                promise.resolve("positive");
            } else {
                Toast.makeText(activity, "网络出错,请稍后再试", Toast.LENGTH_LONG).show();
                promise.resolve("negative");
            }
        } else {
            Uri packageURI = Uri.parse("package:" + activity.getPackageName());
            Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES, packageURI);
            activity.startActivity(intent);
            promise.resolve("negative");
        }
    }

    private static boolean checkInstallPermission(Context context) {
        // if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        //     return context.getPackageManager().canRequestPackageInstalls();
        // }
        return true;
    }

    @ReactMethod
    public void execCommand(String cmd, final Promise promise) {
        String[] commands = {cmd};
        InstallUtils.CommandResult commandResult = InstallUtils.execCmd(commands, null,true, true);
        WritableMap map = Arguments.createMap();
        map.putInt("result",commandResult.result);
        map.putString("success", commandResult.successMsg);
        map.putString("error", commandResult.errorMsg);
        promise.resolve(map);
    }

    @Override
    public void onHostResume() {
        // Activity `onResume`
    }

    @Override
    public void onHostPause() {
        // Activity `onPause`
    }

    @Override
    public void onHostDestroy() {
        // Activity `onDestroy`
        mBroadcastManager.unregisterReceiver(mBroadcastReceiver);
        reactContext.removeLifecycleEventListener(this);
        reactContext.removeActivityEventListener(mActivityEventListener);
    }

    @Override
    public boolean onRequestPermissionsResult(int requestCode,
                                              String permissions[], int[] grantResults) {
        switch (requestCode) {
            case MY_PERMISSIONS_REQUEST_WRITE_STORAGE: {
                // If request is cancelled, the result arrays are empty.
                if (grantResults.length > 0
                        && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    Log.e(TAG,"onRequestPermissionsResult granted");
                    doUnRootDownloadInstallImpl(getCurrentActivity(), this.versionUrl, this.progress, this.promise);
                } else {
                    Log.e(TAG,"onRequestPermissionsResult denied");
                    this.promise.resolve("negative");
                    showWaringDialog();
                }
                return false;
            }
        }
        return true;
    }

    private void showWaringDialog() {
        AlertDialog dialog = new AlertDialog.Builder(getCurrentActivity())
                .setTitle("警告！")
                .setMessage("请前往设置->应用->PermissionDemo->权限中打开相关权限，否则功能无法正常运行！")
                .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        // 一般情况下如果用户不授权的话，功能是无法运行的，做退出处理
                        Intent intent = new Intent();
                        intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                        intent.setData(Uri.fromParts("package", UpgradeLibraryModule.this.reactContext.getPackageName(), null));
                        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                        UpgradeLibraryModule.this.reactContext.startActivity(intent);
                    }
                }).show();
    }
}

